﻿using FluentScheduler;
using Glorysoft.Auto.Xfw;
using Glorysoft.Auto.Xfw.Contract;
using Glorysoft.Auto.Xfw.Entities;
using Glorysoft.EAP.Core;
using Glorysoft.EAP.Core.Entities;
using Glorysoft.EAP.Core.Entities.DB;
using Glorysoft.EAP.Core.Entities.EMS.EAP;
using Glorysoft.EAP.Core.Entities.FT;
using Glorysoft.EAP.Core.Enums;
using Glorysoft.EAP.EAPwell.web;
using Glorysoft.EAP.RC.EAPClient;
using Glorysoft.EAP.RC.MES;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Opc.Ua.Bindings;
using RestSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

namespace Glorysoft.EAP.EAPwell
{
    public class EAPwellServer
    {
        private static readonly Lazy<EAPwellServer> Lazy = new Lazy<EAPwellServer>(() => new EAPwellServer());



        public static EAPwellServer Current => Lazy.Value;
        public static string EAPServer = Dict.Current.EAPName;//"EAPServer";
        public const string NotifyDisconnect = "NotifyDisconnect";
        protected readonly string conn = "1";
        protected readonly string disConn = "-1";
        public DbService dbService = null;
        public MESService mesService = null;

        /// <summary>
        /// 初始化加载
        /// </summary>
        public void InitLoad(IConfiguration config)
        {
            try
            {
                Init(config);
                SetConsoleCtrlHandler(cancelHandler, true);
                Console.WriteLine($"{XfwContext.ServerName} is Initializing.");
                //初始化获取参数信息
                InitializeEAP();
                //Thread.Sleep(2000);
                Dict.Current.EqpConfigDic = XfwContext.GetEQPContexts();
                foreach (KeyValuePair<string, ContextObject> ctx in Dict.Current.EqpConfigDic)
                {
                    var eqpID = ctx.Key;
                    if (!(ctx.Value.AllContexts == null || ctx.Value.AllContexts.Count() == 0))
                    {
                        var ctxx = ctx.Value.AllContexts[0];
                        if (!ctxx.IsConnected)
                        {
                            if (ctxx.Configuration.EqpType.Contains("OCR"))
                            {
                                Dict.Current.OCRCurrentStatus.Add(eqpID, "");
                            }
                            Console.WriteLine($"{DateTime.Now.ToString(CItems.DateTimeFormat)}:设备{eqpID}连接失败");
                            //ReportEqpStateChange(eqpID, "-1");
                            continue;
                        }
                    }
                    Thread.Sleep(10);
                }
                Console.WriteLine($"{XfwContext.ServerName} is Runing.");
  

                var host =
                new WebHostBuilder().
                UseKestrel().
                UseContentRoot(Directory.GetCurrentDirectory()).
                UseUrls("http://0.0.0.0:5000").
                UseStartup<web.Startup>().Build();


                host.Run();
                while (true)
                {
                    //退出
                    string exit = Console.ReadLine();
                    if (exit.ToLower() == "exit")
                    {
                        //Console.ReadLine();
                        Console.WriteLine($"{XfwContext.ServerName} is Terminating.");
                        EAPwellServer.Current.TerminateEAP();
                        Console.WriteLine($"{XfwContext.ServerName} is Exiting.");
                        return;
                    }
                    //Console.ReadKey();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"{DateTime.Now.ToString(CItems.DateTimeFormat)}:EAPwellServer=>InitLoad=>程序错误:{e.Message}");
                
                string exit = Console.ReadLine();
            }
        }

        private void Init(IConfiguration config)
        {
            try
            {
                Dict.Current.MonitorTestDataPath = config.GetSection("MonitorTestDataPath").Get<string>();//MonitorTestDataPath
                Dict.Current.EQPType = config.GetSection("EQPType").Get<string>();//EQPType
                Scheduler.Initialize();
                CItems.IsCheckNeedleMark = config.GetSection("IsCheckNeedleMark").Get<string>();//判断是否检查针痕标志
                CItems.PIBIDValue = config.GetSection("PIBID").Get<string>();//PIB ID
                Dict.Current.TesterID = config.GetSection("TesterID").Get<string>();//TesterID
                Dict.Current.Interval = config.GetSection("Interval").Get<string>();//Daemon心跳间隔时间
                Dict.Current.IsEngineeringMode = config.GetSection("IsEngineeringMode").Get<string>();// 
                Dict.Current.ProberRecipe = config.GetSection("ProberRecipe").Get<string>();// 
                Dict.Current.ProberLotID = config.GetSection("ProberLotID").Get<string>();// 
                XfwContext.Configuration = config;
                XfwContext.ServerName = config.GetSection("EAPNo").Get<string>();
                Dict.Current.DataSource = config.GetSection("DataSource").Get<string>();//MASCCESS_DB

                Dict.Current.OdysseyIP = config.GetSection("OdysseyIP").Get<string>();// Odyssey webServiceIP地址


                CItems.FtpAddress = config.GetSection("FtpAddress").Get<string>();
                CItems.FtpPort = config.GetSection("FtpPort").Get<int>();
                CItems.FtpUserName = config.GetSection("FtpUserName").Get<string>();
                CItems.FtpPassword = config.GetSection("FtpPassword").Get<string>();
                CItems.CheckZHType = config.GetSection("CheckZHType").Get<string>();
                CItems.CheckZHPath = config.GetSection("CheckZHPath").Get<string>();
                CItems.CheckZHUPLOADPath = config.GetSection("CheckZHUPLOADPath").Get<string>();
                CItems.CheckZHTime = config.GetSection("CheckZHTime").Get<int>();
                CItems.TrackOutSleep = config.GetSection("TrackOutSleep").Get<int>();
                CItems.TrackOutCount = config.GetSection("TrackOutCount").Get<int>();
                CItems.CheckFile = config.GetSection("CheckFile").Get<int>();
                CItems.TrackOutFailInfo = config.GetSection("TrackOutFailInfo").Get<string>();
                CItems.IsTest = config.GetSection("IsTest").Get<string>();
                ReadJson();
                JobManager.Initialize(new MyRegistry());//type1 monitor测试监控
                //MSAccessHelper mSAccessHelper = new MSAccessHelper();
                //var jieguo = "";
                //jieguo = mSAccessHelper.MSAccessConnectQuery("BYCPT33", "0693-16S-FLEX-05", "0693");
                //if (Dict.Current.EQPType == "Type1")
                //{
                //    Dict.Current.RunMonitorRemindWeek = config.GetSection("RunMonitorRemindWeek").Get<string>();
                //    Dict.Current.RunMonitorRemindHour = config.GetSection("RunMonitorRemindHour").Get<string>();
                //    Dict.Current.RunMonitorLotId = config.GetSection("RunMonitorLotId").Get<string>();//lotid
                //    Dict.Current.RunMonitorRecipeId = config.GetSection("RunMonitorRecipeId").Get<string>();//recipe
                //    JobManager.Initialize(new MyRegistry());//type1 monitor测试监控
                //}
                // Dict.Current.LotOutTime = config.GetSection("LotOutTime").Get<string>();//多长时间发送一次TrackOut给MES（分钟）
                // Dict.Current.LotOutCount = config.GetSection("LotOutCount").Get<string>();//每个批次只能发送的次数
                // Dict.Current.EAPDB = config.GetSection("EAPDB").Get<string>();//EAPDB
                // dbService = new DbService();
                // mesService = new MESService();
                // var interval = Convert.ToInt32(Dict.Current.LotOutTime) * 60;
                // Scheduler.Add("LotOutToMES", interval, ScheduleOptions.Loop, new Action<object>(obj => LotOutToMES()), null);
                // Scheduler.Add("test", 3, ScheduleOptions.Loop, new Action<object>(obj => test()), null);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{DateTime.Now.ToString(CItems.DateTimeFormat)}:EAPwellServer=>InitLoad=>程序错误:{ex.Message}");
            }

        }

        #region 初始化私有方法
        /// <summary>
        /// eap启动执行
        /// </summary>
        private void InitializeEAP()
        {
            try
            {
                XfwContext.InitializationXfw();
                XfwContext.StartXfw();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        /// <summary>
        /// eap退出执行
        /// </summary>
        private void TerminateEAP()
        {
            XfwContext.TerminateXfw();
            EAPDisconnect();
        }

        #endregion

        #region   Server关闭，将断开信息报给Client
        public delegate bool ControlCtrlDelegate(int CtrlType);
        [DllImport("kernel32.dll")]
        private static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate HandlerRoutine, bool Add);
        private static ControlCtrlDelegate cancelHandler = new ControlCtrlDelegate(HandlerRoutine);
        public static bool HandlerRoutine(int CtrlType)
        {
            switch (CtrlType)
            {
                case 0: //Ctrl+C关闭
                case 2://按控制台关闭按钮关闭
                    EAPDisconnect();
                    break;
            }
            Console.ReadLine();
            return false;
        }

        public static void EAPDisconnect()
        {
            try
            {
                EAPServer = Dict.Current.EAPName;
                var request = new Publish() { Header = XfwUtils.CreateHeader(NotifyDisconnect, EAPServer) };
                request.Body.AddString(CItems.EqpID, Dict.Current.DaemonName);
                var strText = XfwUtils.Serialization(request.GetSerializationObject());
                var context = XfwContext.GetMqContextByEAP(EAPServer);
                context.Publish(strText);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }
        #endregion

        /// <summary>
        /// 获取EAP.json中的文件信息
        /// </summary>
        private void ReadJson()
        {
            try
            {
                StreamReader sr = new StreamReader(System.IO.Directory.GetCurrentDirectory() + "\\Configuration\\EAP.json", System.Text.Encoding.Default);
                String line;
                string jsonobj = "";
                while ((line = sr.ReadLine()) != null)
                {
                    if (line.Contains("//"))
                    {
                        continue;
                    }
                    jsonobj = jsonobj + line.ToString();
                }
                XmlDictionaryReader reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(jsonobj), XmlDictionaryReaderQuotas.Max);
                XmlDocument XmlDoc = new XmlDocument();
                XmlDoc.Load(reader);

                string Name = XmlDoc.SelectSingleNode("//Name").InnerText;
                Dict.Current.EAPName = Name;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        #region  待删除
        //private void LotOutToMES()
        //{
        //    try
        //    {
        //        var testID = Dict.Current.TesterID;
        //        var runHisTempList = dbService.SelectRunHisTempByEQPID(testID);
        //        foreach (var runHisTemp in runHisTempList)
        //        {
        //            if (!Dict.Current.LotOutNum.ContainsKey(runHisTemp.LOT_ID))
        //            {
        //                Dict.Current.LotOutNum.Add(runHisTemp.LOT_ID, Convert.ToInt32(Dict.Current.LotOutCount));
        //            }
        //            if (Dict.Current.LotOutNum[runHisTemp.LOT_ID] > 0)
        //            {
        //                var resultOut = mesService.TrackOut(runHisTemp);//出站识别
        //                if (resultOut == 0)
        //                {
        //                    runHisTemp.TRACKOUT_TIME = DateTime.Now.ToString();
        //                    dbService.UpdateRunHsiTempByID(runHisTemp);
        //                    Dict.Current.LotOutNum.Remove(runHisTemp.LOT_ID);
        //                }
        //                else if (resultOut == 1)
        //                {
        //                    runHisTemp.TRACKOUT_TIME = DateTime.Now.ToString();
        //                    runHisTemp.REMARK = "当前批次已MA手动出站，EAP停止向MES发送出站";
        //                    dbService.UpdateRunHsiTempByID(runHisTemp);
        //                    Dict.Current.LotOutNum.Remove(runHisTemp.LOT_ID);
        //                }
        //                else
        //                {
        //                    Dict.Current.LotOutNum[runHisTemp.LOT_ID]--;
        //                }
        //            }
        //            else
        //            {
        //                runHisTemp.TRACKOUT_TIME = DateTime.Now.ToString();
        //                runHisTemp.REMARK = "规定次数内无法出站，EAP停止向MES发送出站";
        //                dbService.UpdateRunHsiTempByID(runHisTemp);
        //                Dict.Current.LotOutNum.Remove(runHisTemp.LOT_ID);
        //            }

        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Console.WriteLine(ex.Message);
        //    }

        //}


        //public void SendHeartBeat()
        //{
        //    try
        //    {
        //        EAPClientService clientService = new EAPClientService();
        //        var eqpID = Dict.Current.TesterID;
        //        string eapStatus = "";
        //        ContextObject eqpcontexts = Dict.Current.EqpConfigDic[eqpID];

        //        var ctx = eqpcontexts?.AllContexts[0] as IDaemonContext;
        //        var req = new Request() { Header = XfwUtils.CreateHeader("HeartBeat") };
        //        JObject jObject = new JObject();
        //        jObject.AddString(CItems.TesterEqpID, eqpID);
        //        req.Body = jObject;
        //        var resp = ctx.Request(req);
        //        if (resp != null)
        //        {

        //            if (resp.Return.ReturnCode == "OK")
        //            {
        //                eapStatus = conn;
        //            }
        //            else
        //            {
        //                eapStatus = disConn;

        //            }
        //        }
        //        else
        //        {
        //            eapStatus = disConn;
        //        }
        //        clientService.EqpStatusReport(eqpID, eapStatus);

        //    }
        //    catch (Exception ex)
        //    {
        //        Console.WriteLine(ex.Message);
        //    }
        //}
        #endregion
    }
}
